package com.ichi2.anki.pj2;

import android.app.Activity;

import com.ichi2.anki.CardBrowser;
import com.ichi2.anki.R;

import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.lang.*;
import java.text.SimpleDateFormat;
import java.util.Date;

import androidx.test.espresso.action.ViewActions;
import androidx.test.espresso.matcher.ViewMatchers;
import androidx.test.ext.junit.rules.ActivityScenarioRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;

import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.clearText;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard;

import static androidx.test.espresso.action.ViewActions.longClick;
import static androidx.test.espresso.action.ViewActions.pressBack;

import static androidx.test.espresso.action.ViewActions.pressKey;
import static androidx.test.espresso.action.ViewActions.pressMenuKey;

import static androidx.test.espresso.action.ViewActions.typeText;

import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;

import static androidx.test.espresso.matcher.ViewMatchers.withContentDescription;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withSpinnerText;
import static androidx.test.espresso.matcher.ViewMatchers.withText;


/**
 * Basic tests showcasing simple view matchers and actions like {@link ViewMatchers#withId},
 * {@link ViewActions#click} and {@link ViewActions#typeText}.
 * <p>
 * Note that there is no need to tell Espresso that a view is in a different {@link Activity}.
 * 连接模拟器：nox_adb.exe connect 127.0.0.1:62001
 */
@RunWith(AndroidJUnit4.class)
@LargeTest
public class CardBrowserTest {
    @Rule
    public ActivityScenarioRule<CardBrowser> activityScenarioRule = new ActivityScenarioRule<>(CardBrowser.class);

    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
    String date = df.format(new Date());


    /**
     * 用于增加测试数据的函数
     */
    public void add_data() {
        // 新增deck
        onView(withId(R.id.dropdown_deck_name)).perform(click());
        onView(withId(R.id.deck_picker_dialog_action_add_deck)).perform(click());
        onView(withId(R.id.md_input_message)).perform(typeText("deck_test_" + date));
        onView(withId(R.id.md_button_positive)).perform(click());

        // 新增两个card
        onView(withContentDescription("Add")).perform(click());
        onView(withContentDescription("Front")).perform(click(), typeText("Front1_" + date));
        onView(withContentDescription("Back")).perform(click(), typeText("Back_1" + date), closeSoftKeyboard());
        onView(withContentDescription("Save")).perform(click());

        onView(withContentDescription("Front")).perform(click(), typeText("Front2_" + date));
        onView(withContentDescription("Back")).perform(click(), typeText("Back_2" + date), closeSoftKeyboard());
        onView(withContentDescription("Save")).perform(click());
        onView(withContentDescription("Navigate up")).perform(click());
    }


    /**
     * 点击三条杠显示侧边栏,跳转到decks
     */
    @Test
    public void show_side_decks() {
        onView(withContentDescription("Open drawer")).perform(click());
        onView(withText("Decks")).perform(click());
        onView(withId(R.id.deckpicker_view)).check(matches(isDisplayed()));
    }


    /**
     * 点击三条杠显示侧边栏,跳转到cardbrowser
     */
    @Test
    public void show_side_card() {
        onView(withContentDescription("Open drawer")).perform(click());
        onView(withText("Card browser")).perform(click());
        onView(withId(R.id.card_browser_list)).check(matches(isDisplayed()));
    }


    /**
     * 点击三条杠显示侧边栏,跳转到statistics
     */
    @Test
    public void show_side_Statistics() {
        onView(withContentDescription("Open drawer")).perform(click());
        onView(withText("Statistics")).perform(click());
        onView(withId(R.id.web_view_stats)).check(matches(isDisplayed()));
    }


    /**
     * 点击三条杠显示侧边栏,跳转到settings
     */
    @Test
    public void show_side_settings() {
        onView(withContentDescription("Open drawer")).perform(click());
        onView(withText("Settings")).perform(click());
        onView(withId(R.id.settings_container)).check(matches(isDisplayed()));
    }


    /**
     * 点击三条杠显示侧边栏,显示help
     */
    @Test
    public void show_side_help() {
        onView(withContentDescription("Open drawer")).perform(click());
        onView(withText("Help")).perform(click());
        onView(withText("Help")).check(matches(isDisplayed()));
    }


    /**
     * 点击三条杠显示侧边栏,显示support
     */
    @Test
    public void show_side_support() {
        onView(withContentDescription("Open drawer")).perform(click());
        onView(withText("Support AnkiDroid")).perform(click());
        onView(withText("Support AnkiDroid")).check(matches(isDisplayed()));
    }


    /**
     * 切换deck
     */
    @Test
    public void switch_deck() {
        add_data();
        onView(withId(R.id.dropdown_deck_name)).perform(click());
        onView(withText("All decks")).perform(click());
        onView(withId(R.id.dropdown_deck_name)).check(matches(withText("All decks")));
    }


    /**
     * 新增deck
     */
    @Test
    public void add_deck() {
        add_data();
        onView(withId(R.id.dropdown_deck_name)).perform(click());
        onView(withId(R.id.deck_picker_dialog_action_add_deck)).perform(click());
        onView(withId(R.id.md_input_message)).perform(typeText("deck_test_1" + date));
        onView(withId(R.id.md_button_positive)).perform(click());
        onView(withId(R.id.dropdown_deck_name)).check(matches(withText("deck_test_1" + date)));
    }


    /**
     * 搜索deck
     */
    @Test
    public void search_deck() {
        onView(withId(R.id.dropdown_deck_name)).perform(click());
        onView(withId(R.id.deck_picker_dialog_action_filter)).perform(click());
        onView(withId(R.id.search_src_text)).perform(typeText("All"));
        onView(withText("All decks")).check(matches(isDisplayed()));
    }


    /**
     * 卡片计数器显示
     */
    @Test
    public void count() {
        add_data();
        onView(withId(R.id.dropdown_deck_counts)).check(matches(withText("2 cards shown")));
    }


    /**
     * 新增卡片
     */
    @Test
    public void add_cards() {
        add_data();
        // 新增card
        onView(withContentDescription("Add")).perform(click());
        onView(withContentDescription("Front")).perform(click(), typeText("Front_add" + date));
        onView(withContentDescription("Back")).perform(click(), typeText("Back_add" + date), closeSoftKeyboard());
        onView(withContentDescription("Save")).perform(click());
        onView(withContentDescription("Navigate up")).perform(click());

        onView(withText("Front_add" + date)).check(matches(isDisplayed()));
    }


    /**
     * 搜索卡片
     */
    @Test
    public void search_cards() {
        add_data();
        onView(withContentDescription("Search")).perform(click());
        onView(withId(R.id.search_src_text)).perform(typeText("Front1_"));
        onView(withText("Front1_" + date)).check(matches(isDisplayed()));
    }


    /**
     * 点击菜单显示选项
     */
    @Test
    public void switch_order() {
        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Change display order")).perform(click());
        onView(withText("By ease")).perform(click());
        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Change display order")).perform(click());
        onView(withText("No sorting (faster)")).perform(click());

        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Filter marked")).perform(click());
        pressBack();
        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Filter suspended")).perform(click());
        pressBack();

        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Filter by tag")).perform(click());
        onView(withText("Select")).perform(click());

        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Filter by flag")).perform(click());
        onView(withText("Red flag")).perform(click());
        pressBack();

        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Options")).perform(click());
        onView(withText("Cards")).perform(click());
        onView(withText("OK")).perform(click());

        onView(withText("Options")).check(doesNotExist());
    }


    /**
     * 切换卡片的 front
     */
    @Test
    public void switch_front() {
        add_data();
        onView(withId(R.id.browser_column1_spinner)).perform(click());
        onView(withText("Sort field")).perform(click());
        onView(withId(R.id.browser_column1_spinner)).check(matches(withSpinnerText("Sort field")));
    }


    /**
     * 切换卡片的 back
     */
    @Test
    public void switch_back() {
        add_data();
        onView(withId(R.id.browser_column2_spinner)).perform(click());
        onView(withText("Answer")).perform(click());
        onView(withId(R.id.browser_column2_spinner)).perform(click());
        onView(withText("Deck")).perform(click());
        onView(withId(R.id.browser_column2_spinner)).perform(click());
        onView(withText("Note")).perform(click());
        onView(withId(R.id.browser_column2_spinner)).perform(click());
        onView(withText("Question")).perform(click());
        onView(withId(R.id.browser_column2_spinner)).perform(click());
        onView(withText("Tags")).perform(click());
        onView(withId(R.id.browser_column2_spinner)).perform(click());
        onView(withText("Lapses")).perform(click());
        onView(withId(R.id.browser_column2_spinner)).perform(click());
        onView(withText("Reviews")).perform(click());
        onView(withId(R.id.browser_column2_spinner)).perform(click());
        onView(withText("Interval")).perform(click());
        onView(withId(R.id.browser_column2_spinner)).perform(click());
        onView(withText("Ease")).perform(click());
        onView(withId(R.id.browser_column2_spinner)).perform(click());
        onView(withText("Due")).perform(click());
        onView(withId(R.id.browser_column2_spinner)).perform(click());
        onView(withText("Card Modified")).perform(click());
        onView(withId(R.id.browser_column2_spinner)).perform(click());
        onView(withText("Created")).perform(click());
        onView(withId(R.id.browser_column2_spinner)).perform(click());
        onView(withText("Note Modified")).perform(click());
        onView(withId(R.id.browser_column2_spinner)).perform(click());
        onView(withText("Card")).perform(click());

        onView(withId(R.id.browser_column2_spinner)).check(matches(withSpinnerText("Card")));
    }


    /**
     * 点击卡片编辑,预览
     */
    @Test
    public void edit_card() {
        add_data();
        onView(withText("Front1_" + date)).perform(click());
        onView(withContentDescription("Front")).perform(click(), clearText(), typeText("edit_" + date));
        onView(withContentDescription("Save")).perform(click());
        onView(withText("edit_" + date)).check(matches(isDisplayed()));
        onView(withText("edit_" + date)).perform(click());
        // 复制笔记
        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Copy note")).perform(click());
        // 修改字体大小
        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Font size")).perform(click());
        onView(withText("Cancel")).perform(click());
        // 修改其他配置
        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Capitalize sentences")).perform(click());

        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Show toolbar")).perform(click());
        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Scroll toolbar")).perform(click());
        // 点击预览
        onView(withContentDescription("Preview")).perform(click());

        onView(withText("edit_" + date)).check(doesNotExist());
    }


    /**
     * 长按选择卡片
     */
    @Test
    public void choose_card() {
        add_data();
        onView(withText("Front1_" + date)).perform(longClick());
        // 长按加旗子
        onView(withId(R.id.action_flag)).perform(click());
        onView(withText("Red flag")).perform(click());
        // 标记
        onView(withId(R.id.action_mark_card)).perform(click());
        // 长按编辑
        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Edit note")).perform(click());
        onView(withContentDescription("Navigate up")).perform(click());
        onView(withText("Front1_" + date)).perform(longClick());
        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Card info")).perform(click());
        onView(withContentDescription("Navigate up")).perform(click());

        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Suspend cards")).perform(click());
        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Unsuspend cards")).perform(click());

        onView(withText("Front1_" + date)).perform(longClick());
        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Reposition")).perform(click());
        onView(withId(R.id.md_input_message)).perform(click(), typeText("5"));
        onView(withText("OK")).perform(click());

        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Undo reposition")).perform(click());
        onView(withText("Front1_" + date)).perform(longClick());

        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Reschedule")).perform(click());
        onView(withId(R.id.md_input_message)).perform(click(), typeText("5"));
        onView(withText("OK")).perform(click());

        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Edit tags")).perform(click());
        onView(withText("OK")).perform(click());

        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Reset progress")).perform(click());
        onView(withText("OK")).perform(click());

        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Preview")).perform(click());
        pressBack();
        onView(withContentDescription("Navigate up")).perform(click());

        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Select all")).perform(click());

        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Suspend cards")).perform(click());

        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Unsuspend cards")).perform(click());

        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Reposition")).perform(click());
        onView(withId(R.id.md_input_message)).perform(click(), typeText("5"));
        pressKey(23);
        onView(withText("OK")).perform(click());

        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Reschedule")).perform(click());
        onView(withId(R.id.md_input_message)).perform(click(), typeText("5"));
        onView(withText("OK")).perform(click());

        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Edit tags")).perform(click());
        onView(withText("OK")).perform(click());

        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Reset progress")).perform(click());
        onView(withText("OK")).perform(click());

        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Preview")).perform(click());
        onView(withContentDescription("Navigate up")).perform(click());

        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Select none")).perform(click());

        // 删除
        onView(withText("Front1_" + date)).perform(longClick());
        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Select all")).perform(click());
        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Delete notes")).perform(click());
        pressBack();

        onView(withId(R.id.list)).check(doesNotExist());
    }


    /**
     * 移动卡片
     */
    @Test
    public void move_card() {
        add_data();
        onView(withText("Front1_" + date)).perform(longClick());
        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Change deck")).perform(click());
        onView(withContentDescription("Add")).perform(click());
        onView(withId(R.id.md_input_message)).perform(typeText("deck_test2_" + date));
        onView(withId(R.id.md_button_positive)).perform(click());

        onView(withId(R.id.list)).check(doesNotExist());
    }
}
